home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / FPSE_src / emu.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  12KB  |  471 lines

  1. /*
  2.     FPSE main()
  3.     ===========
  4.  
  5.     Written by BERO
  6.     Modified by LDChen
  7. */
  8.  
  9. #include "fpse.h"
  10.  
  11. // FPSE can use this executables:
  12. #define PSX_EXE     1
  13. #define CPE_EXE     2
  14. #define COFF_EXE    3
  15. #define INVALID_EXE 4
  16.  
  17. // Actually these are unused, but in the future...
  18. #if 0
  19. // Section names of COFF format:
  20. static char text_name[]  = { ".text"  };
  21. static char rdata_name[] = { ".rdata" };
  22. static char data_name[]  = { ".data"  };
  23. static char sdata_name[] = { ".sdata" };
  24. static char sbss_name[]  = { ".sbss"  };
  25. static char bss_name[]   = { ".bss"   };
  26.  
  27. static char *COFF_Names[8] = {
  28.     text_name,
  29.     rdata_name,
  30.     data_name,
  31.     sdata_name,
  32.     sbss_name,
  33.     bss_name,
  34.     NULL,
  35.     NULL
  36. };
  37. #endif
  38.  
  39. #define SCOFF_TEXT      0
  40. #define SCOFF_RDATA     1
  41. #define SCOFF_DATA      2
  42. #define SCOFF_SDATA     3
  43. #define SCOFF_SBSS      4
  44. #define SCOFF_BSS       5
  45. #define SCOFF_UNKNOWN   6
  46.  
  47. unsigned char *rom,*ram,*scratchpad,*extrom;
  48.  
  49. int FPSE_Flags = EMULATE_BIOS | COMPILE;
  50.  
  51. extern int breakpoint;
  52.  
  53. static char ActionR[] = { "ar.rom" };
  54.  
  55. static UINT32 FSize(FILE *f)
  56. {
  57.     UINT32 curpos = ftell(f);
  58.     UINT32 endpos;
  59.  
  60.     fseek(f,0L,SEEK_END);
  61.     endpos = ftell(f);
  62.     fseek(f,curpos,SEEK_SET);
  63.  
  64.     return endpos;
  65. }
  66.  
  67. static int PSXGetFileType(FILE *f)
  68. {
  69.     UINT32      current;
  70.     UINT8       mybuf[2048];
  71.     EXE_HEADER *exe_hdr;
  72.     FILHDR     *coff_hdr;
  73.  
  74.     current = ftell(f);
  75.     fseek(f,0L,SEEK_SET);
  76.     fread(mybuf,2048,1,f);
  77.     fseek(f,current,SEEK_SET);
  78.  
  79.     exe_hdr = (EXE_HEADER *)mybuf;
  80.     if (memcmp(exe_hdr->id,"PS-X EXE",8)==0)
  81.         return PSX_EXE;
  82.  
  83.     if (mybuf[0]=='C' && mybuf[1]=='P' && mybuf[2]=='E')
  84.         return CPE_EXE;
  85.  
  86.     coff_hdr = (FILHDR *)mybuf;
  87.     if (coff_hdr->f_magic == 0x0162)
  88.         return COFF_EXE;
  89.  
  90.     return INVALID_EXE;
  91. }
  92.  
  93. #if 0
  94. static int COFFSectionName(char *str)
  95. {
  96.     int x;
  97.  
  98.     COFF_Names[SCOFF_UNKNOWN] = str;
  99.     for (x=SCOFF_TEXT; x<=SCOFF_UNKNOWN; x++)
  100.         if (!strcmp(str,COFF_Names[x])) break;
  101.  
  102.     return x;
  103. }
  104. #endif
  105.  
  106. static int PSXLoadFile(char *nf, UINT32 addr, int flags)
  107. {
  108.     FILE      *fp;
  109.     EXE_HEADER head;
  110.     int        type;
  111.     int        size;
  112.     UINT8     *mybuf;
  113.     UINT8     *buf;
  114.     FILHDR    *coff_hdr;
  115.     AOUTHDR   *opt_hdr;
  116.     SCNHDR    *section;
  117.  
  118.     fp = fopen(nf,"rb");
  119.     if (fp==NULL) return FPSE_ERR;
  120.  
  121.     if (addr)
  122.     {
  123.         printf("Loading %s at %08x\n",nf,(int)addr);
  124.         size = FSize(fp);
  125.         fread(ram + (addr & 0x1FFFFF),1,size,fp);
  126.     } else {
  127.         type = PSXGetFileType(fp);
  128.         switch (type) {
  129.         case PSX_EXE:
  130.             fread(&head,1,sizeof(head),fp);
  131.             head.t_addr = SWAP32(head.t_addr);
  132.             head.t_size = SWAP32(head.t_size);
  133.             head.pc0 = SWAP32(head.pc0);
  134.             head.s_addr = SWAP32(head.s_addr);
  135.             printf("Loading %s (PS_EXE) at %08x-%08x\n",
  136.                    nf,(int)head.t_addr,(int)head.t_addr+(int)head.t_size);
  137.             fread(&ram[head.t_addr&0x1fffff],1,head.t_size,fp);
  138.             if (flags)
  139.             {
  140.                 printf("Setting up PC=%08x\n",(int)head.pc0);
  141.                 setpc(head.pc0);
  142.                 reg.r[30] = reg.r[29] = head.s_addr;
  143.                 reg.r[31] = 0;
  144.             }
  145.             break;
  146.         case CPE_EXE:
  147.             printf("Loading %s (CPE_EXE)\n",nf);
  148.             size = FSize(fp);
  149.             mybuf = (UINT8*)malloc(size);
  150.             fread(mybuf,1,size,fp);
  151.             buf = mybuf + 6;
  152.             while (*buf)
  153.             {
  154.                 switch (*buf) {
  155.                 case 3:
  156.                     if (flags)
  157.                     {
  158.                         UINT32 myPc = *(UINT32 *)(buf + 3);
  159.  
  160.                         printf("Setting up PC=%08x\n",(int)myPc);
  161.                         setpc(myPc);
  162.                         reg.r[30] = reg.r[29] = 0x801FFFF0;
  163.                         reg.r[31] = 0;
  164.                         buf += 7;
  165.                     }
  166.                     break;
  167.                 case 1:
  168.                     {
  169.                     UINT32 base,size;
  170.  
  171.                     base = *(UINT32 *)(buf + 1);
  172.                     size = *(UINT32 *)(buf + 5);
  173.  
  174.                     PRINTF("Base Address = 0x%08x Size = 0x%08x(%d)\n" ,
  175.                             (int)base , (int)size , (int)size);
  176.                     memcpy(&ram[base & 0x1FFFFF], buf + 9, size);
  177.                     buf += 9+size;
  178.                     break;
  179.                     }
  180.                 default:
  181.                     printf("Unknown id field 0x%02x at offset 0x%08x" ,
  182.                             *buf, (int)(buf - mybuf));
  183.                     free(mybuf);
  184.                     fclose(fp);
  185.                     return FPSE_ERR;
  186.                 }
  187.             }
  188.             free(mybuf);
  189.             break;
  190.         case COFF_EXE:
  191.             printf("Loading %s (COFF_EXE)\n",nf);
  192.             size = FSize(fp);
  193.             mybuf = (UINT8*)malloc(size);
  194.             fread(mybuf,1,size,fp);
  195.             coff_hdr = (FILHDR *)mybuf;
  196.             opt_hdr  = (AOUTHDR*)(coff_hdr+1);
  197.             section = (SCNHDR *)(mybuf + FILHSZ + coff_hdr->f_opthdr);
  198.  
  199.             if (flags)
  200.             {
  201.                 printf("Setting up PC=%08x\n",(int)opt_hdr->entry);
  202.                 setpc(0x80010030);
  203.                 reg.r[30] = reg.r[29] = 0x801fff00;
  204.                 reg.r[31] = opt_hdr->entry;
  205.             }
  206.  
  207.             for (size = 0; size < coff_hdr->f_nscns ; size++)
  208.             {
  209. /*
  210.                 if (flags)
  211.                 {
  212.                     switch (COFFSectionName(section->s_name)) {
  213.                     case SCOFF_BSS:
  214.                         break;
  215.                     }
  216.                 }
  217. */
  218.                 PRINTF("%8s at %08x size %08x\n",
  219.                        section->s_name,
  220.                        (int)section->s_paddr,
  221.                        (int)section->s_size);
  222.  
  223.                 if (section->s_scnptr)
  224.                     memcpy(&ram[(section->s_paddr) & 0x1FFFFF],
  225.                        mybuf+section->s_scnptr,section->s_size);
  226.                 else memset(&ram[(section->s_paddr) & 0x1FFFFF],
  227.                             0,section->s_size);
  228.  
  229.                 section++;
  230.             }
  231.             free(mybuf);
  232.             break;
  233.         case INVALID_EXE:
  234.             printf("ERROR: %s not a valid EXE file.\n",nf);
  235.             break;
  236.         }
  237.     }
  238.  
  239.     fclose(fp);
  240.  
  241.     return FPSE_OK;
  242. }
  243.  
  244. static char helpmsg[] = 
  245.     "\nSyntax: fpse [-option] [file]\n"
  246.     " file         PSX-EXE file\n"
  247.     " -c           compiler(default)\n"
  248.     " -i           interpriter\n"
  249.     " -b<biosfile> bios filename\n"
  250.     " -a<romfile>  load A/R Flash\n"
  251.     " -v           verbose\n"
  252.     " -d           disassemble\n"
  253.     " -e           run debugger\n"
  254.     " -s<script>   script file name\n"
  255.     " -?           display this help screen\n";
  256.  
  257.  
  258. int main(int argc,char *argv[])
  259. {
  260.     FILE  *fp         = NULL;
  261.     char  *file       = NULL;
  262.     char  *scriptfile = NULL;
  263.     char  *flashfile  = NULL;
  264.     char   buffer[80];
  265.     char   cmd[8];
  266.     char   filename[80];
  267.     UINT32 address;
  268.     int    i,line;
  269.  
  270. //   breakpoint = 0x8003ace8;
  271.  
  272.     printf("FPSE - *FREE* PlayStation Emulator\n"
  273.            "%s Version %2x.%02x\n\n"
  274.            "Written by BERO and LDCHEN\n",
  275.            OS_Name,FPSE_VERSION>>8, FPSE_VERSION & 0xFF);
  276.     if (OS_PorterName!=NULL)
  277.         printf("Porting done by %s\n",OS_PorterName);
  278.  
  279.     LoadCFG();
  280.  
  281.     for(i=1;i<argc;i++) {
  282.         char *s = argv[i];
  283.  
  284.         if (s[0]=='-') {
  285.             switch(s[1]) {
  286.             case 'a':
  287.                 if (*(s+2) == 0) flashfile = ActionR;
  288.                 else {
  289.                     flashfile = s+2;
  290.                     FPSE_Flags |= ACTIONREPLAY;
  291.                 } 
  292.                 break;
  293.             case 'c': FPSE_Flags |= COMPILE;   break;
  294.             case 'i': FPSE_Flags &= ~COMPILE;  break;
  295.             case 'v': FPSE_Flags |= VERBOSE;   break;
  296.             case 'd': FPSE_Flags |= DISASMFLG; break;
  297.             case 'b': FPSEIni.BiosName = s+2;  break;
  298.             case 'e': FPSE_Flags |= DEBUG;     break;
  299.             case 's': scriptfile = s+2;        break;
  300.             case '?':
  301.             default:
  302.                 if (OS_CheckOption(s + 1) == FPSE_OK) break;
  303. /* if command line error, displays Messages and exit */
  304.                 INI_Free();
  305.                 printf(helpmsg);
  306.                 if (OS_ExtendedMsg != NULL) {
  307.                     printf("\n%s specific options:\n",OS_Name);
  308.                     printf("%s",OS_ExtendedMsg);
  309.                 }
  310.                 printf("\nPlease read 'readme.txt' and 'terms.txt'"
  311.                        " before start.\n");
  312.                 return -1;
  313.             }
  314.         } else file = s;
  315.     }
  316.  
  317.     memalloc();
  318.     bios_init();
  319.  
  320.     if (hw_init() != FPSE_OK)
  321.     {
  322.         printf("Couldn't initialize the hardware!\n");
  323.         memfree();
  324.         hw_close();
  325.         INI_Free();
  326.         return -1;
  327.     }
  328.  
  329.     compile_init();
  330.     Reset();
  331.  
  332.     if (FPSEIni.BiosName) {
  333.         fp = fopen(FPSEIni.BiosName,"rb");
  334.         if (fp==NULL) {
  335.             strcpy(buffer,"bios\\");
  336.             strcat(buffer,FPSEIni.BiosName);
  337.             fp = fopen(buffer,"rb");
  338.         }
  339.         if (fp==NULL) {
  340.             printf("can't load biosfile\n");
  341.         } else {
  342.             FPSE_Flags &= ~EMULATE_BIOS;
  343.             fread(rom,1,0x80000,fp);
  344.             fclose(fp);
  345. // Now run the BIOS
  346.             i = FPSE_Flags;
  347.             FPSE_Flags &= ~(VERBOSE | DISASMFLG);
  348. //            FPSE_Flags |= VERBOSE | DISASMFLG;
  349.             while(PC != 0x80030000) doInst();
  350.             FPSE_Flags = i;
  351.         }
  352.     }
  353.  
  354.     if (flashfile)
  355.     {
  356.         fp = fopen(flashfile,"rb");
  357.         if (fp==NULL) {
  358.             strcpy(buffer,"actionR\\");
  359.             strcat(buffer,flashfile);
  360.             fp = fopen(buffer,"rb");
  361.         }
  362.         if (fp==NULL) {
  363.             printf("can't load A/R %s, using defaults\n",flashfile);
  364.             flashfile = NULL;
  365.         } else {
  366.             printf("loading %s...\n",flashfile);
  367.             fread(extrom,1,0x20000,fp);
  368.             fclose(fp);
  369.             Reset();
  370.             if (emulate_bios)
  371.             {
  372.                 setpc(*(UINT32 *)(extrom));
  373.                 reg.r[30] = reg.r[29] = 0x801fff00;
  374.                 reg.r[31] = 0;
  375.             }
  376.         }
  377.     }
  378.  
  379.     PSXLoadFile("LibPS.exe",0,0);
  380.  
  381.     if (scriptfile)
  382.     {
  383.         fp = fopen(scriptfile,"rt");
  384.         if (fp != NULL)
  385.         {
  386.             line = 0;
  387.             while (fgets(buffer,sizeof(buffer),fp))
  388.             {
  389.                 line++;
  390.                 i = sscanf(buffer,"%s %s %x",cmd,filename,(int *)&address);
  391.                 if (i != 2 && i != 3)
  392.                 {
  393.                     printf("Syntax error in '%s' line %d.\n",scriptfile,line);
  394.                     break;
  395.                 } else {
  396.                     if (!stricmp(cmd,"run")) {
  397.                          PSXLoadFile(filename,0,1);
  398.                     } else {
  399.                     if (!stricmp(cmd,"load")) {
  400.                         if (i==2) PSXLoadFile(filename,0,0);
  401.                              else PSXLoadFile(filename,address,0);
  402.                         }
  403.                     }
  404.                 }
  405.             }
  406.             fclose(fp);
  407.         } else printf("Script '%s' not found.\n",scriptfile);
  408.     }
  409.  
  410.         
  411.     if (file) PSXLoadFile(file,0,1);
  412.  
  413.     if (debug) run_debug();
  414.           else
  415.     if (compile) compile_go();
  416.             else go();
  417.  
  418.     INI_Free();
  419.  
  420.     memfree();
  421.  
  422.     hw_close();
  423.  
  424.     return 0;
  425. }
  426.  
  427. #if 1
  428. int printlog(char *fmt, ...)
  429. {
  430.      int ret;
  431.  
  432.      va_list argp;
  433.      va_start(argp,fmt);
  434.      ret = vprintf(fmt,argp);
  435.      va_end(argp);
  436.  
  437.      return ret;
  438. }
  439.  
  440. #else
  441. int printlog(char *fmt, ...)
  442. {
  443.      int ret;
  444.  
  445.      va_list argp;
  446.      static char buf[256],prevbuf[256];
  447.      static char *bufp=buf;
  448.      static int count;
  449.  
  450.      va_start(argp,fmt);
  451.      ret = vsprintf(bufp,fmt,argp);
  452.      va_end(argp);
  453.  
  454.      bufp += strlen(bufp);
  455.      if (bufp[-1] != '\n') {
  456.           return ret;
  457.      }
  458.  
  459.      if (strcmp(buf,prevbuf)==0) {
  460.           count++;
  461.      } else {
  462.           if (count) { printf(" %d times\n",count+1); count=0; }
  463.           printf("%s",buf);
  464.           strcpy(prevbuf,buf);
  465.      }
  466.      bufp=buf;
  467.  
  468.      return ret;
  469. }
  470.  
  471. #endif